home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 8 code / Curves in Quickdraw / QD Curves / access library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  7.1 KB  |  324 lines  |  [TEXT/KAHL]

  1. #include <Memory.h>
  2. #include <Fonts.h>
  3. #include <Resources.h>
  4. #include <QuickDraw.h>
  5. #include <FixMath.h>
  6. #include <ToolUtils.h>
  7.  
  8. #include "access library.h"
  9.  
  10. Handle GetNamedSfntHandle(unsigned char* name, short styleWord)
  11. {
  12.     Handle fond = GetNamedResource('FOND', name);
  13.     if (fond && !ResError())
  14.     {    FamRec* frec = (FamRec*)*fond;
  15.         register short* assoc = (short*)(frec + 1);
  16.         register short sfntID = 0;
  17.         register count = *assoc++;
  18.  
  19.         while (count-- >= 0 && !sfntID)
  20.         {    if (*assoc++ == 0)        /* size == 0 means sfnt */
  21.                 if (*assoc++ == styleWord)
  22.                     sfntID = *assoc;
  23.                 else
  24.                     assoc++;
  25.             else
  26.                 assoc += 2;
  27.         }
  28.         if (sfntID)
  29.         {    Handle sfnt = GetResource('sfnt', sfntID);
  30.             if (sfnt && !ResError())
  31.                 return sfnt;
  32.         }
  33.     }
  34.     Debugger();
  35.     return 0;
  36. }
  37.  
  38. Handle GetSfntHandle(short fondID, register short styleWord)
  39. {
  40.     Handle fond = GetResource('FOND', fondID);
  41.     if (fond && !ResError())
  42.     {    FamRec* frec = (FamRec*)*fond;
  43.         register short* assoc = (short*)(frec + 1);
  44.         register short sfntID = 0;
  45.         register count = *assoc++;
  46.  
  47.         while (count-- >= 0 && !sfntID)
  48.         {    if (*assoc++ == 0)        /* size == 0 means sfnt */
  49.                 if (*assoc++ == styleWord)
  50.                     sfntID = *assoc;
  51.                 else
  52.                     assoc++;
  53.             else
  54.                 assoc += 2;
  55.         }
  56.         if (sfntID)
  57.         {    Handle sfnt = GetResource('sfnt', sfntID);
  58.             if (sfnt && !ResError())
  59.                 return sfnt;
  60.         }
  61.     }
  62.     Debugger();
  63.     return 0;
  64. }
  65.  
  66. FontError InitGlyphOutline(GlyphOutline* out)
  67. {
  68.     out->contourCount = 0;
  69.     out->pointCount = 0;
  70.     out->endPoints = (short**)NewHandle(0);
  71.     out->onCurve = (Byte**)NewHandle(0);
  72.     out->x = (Fixed**)NewHandle(0);
  73.     out->y = (Fixed**)NewHandle(0);
  74. }
  75.  
  76. FontError KillGlyphOutline(GlyphOutline* out)
  77. {
  78.     DisposHandle((Handle)out->endPoints);
  79.     DisposHandle((Handle)out->onCurve);
  80.     DisposHandle((Handle)out->x);
  81.     DisposHandle((Handle)out->y);
  82.  
  83.     return fNoError;
  84. }
  85.  
  86. void LockGlyphOutline(GlyphOutline* out)
  87. {
  88.     HLock((Handle)out->endPoints);
  89.     HLock((Handle)out->onCurve);
  90.     HLock((Handle)out->x);
  91.     HLock((Handle)out->y);
  92. }
  93.  
  94. void UnlockGlyphOutline(GlyphOutline* out)
  95. {
  96.     HUnlock((Handle)out->endPoints);
  97.     HUnlock((Handle)out->onCurve);
  98.     HUnlock((Handle)out->x);
  99.     HUnlock((Handle)out->y);
  100. }
  101.  
  102. void MoveGlyphOutline(GlyphOutline* out, Fixed xDelta, Fixed yDelta)
  103. {    
  104.     Fixed* x = *out->x;
  105.     Fixed* y = *out->y;
  106.     short count = out->pointCount;
  107.  
  108.     for (--count; count >= 0; --count)
  109.     {    *x++ += xDelta;
  110.         *y++ += yDelta;
  111.     }
  112.     out->origin.x += xDelta;
  113.     out->origin.y += yDelta;
  114. }
  115.  
  116. void MoveToGlyphOutline(GlyphOutline* out, Fixed xCoord, Fixed yCoord)
  117. {
  118.     MoveGlyphOutline(out, xCoord - out->origin.x, yCoord - out->origin.y);
  119. }
  120.  
  121. void ScaleGlyphOutline(GlyphOutline* out, Fixed xScale, Fixed yScale)
  122. {    
  123.     Fixed* x = *out->x;
  124.     Fixed* y = *out->y;
  125.     short count = out->pointCount;
  126.  
  127.     for (--count; count >= 0; --count)
  128.     {    *x = FixMul( *x, xScale );
  129.         x++;
  130.         *y = FixMul( *y, yScale );
  131.         y++;
  132.     }
  133.     out->origin.x = FixMul( out->origin.x, xScale );
  134.     out->origin.y = FixMul( out->origin.y, yScale );
  135.     out->advance.x = FixMul( out->advance.x, xScale );
  136.     out->advance.y = FixMul( out->advance.y, yScale );
  137. }
  138.  
  139. void InitMatrix(Matrix mat)
  140. {
  141.     mat[0][0] = mat[1][1] = mat[2][2] = 0x10000;
  142.     mat[0][1] = mat[0][2] = mat[1][0] = mat[1][2] = mat[2][0] = mat[2][1] = 0;
  143. }
  144.  
  145. void MapGlyphOutline(GlyphOutline* out, Matrix mat)
  146. {
  147.     Fixed* x = *out->x;
  148.     Fixed* y = *out->y;
  149.     short count = out->pointCount;
  150.     Fixed transX = mat[2][0] - out->origin.x;
  151.     Fixed transY = mat[2][1] - out->origin.y;
  152.  
  153.     for (--count; count >= 0; --count)
  154.     {    Fixed* m0 = &mat[0][0];
  155.         Fixed* m1 = &mat[1][0];
  156.         Fixed xTemp = *x;
  157.         Fixed yTemp = *y;
  158.  
  159.         *x = FixMul(*m0++, xTemp) + FixMul(*m1++, yTemp) + transX;
  160.         *y = FixMul(*m0++, xTemp) + FixMul(*m1++, yTemp) + transY;
  161.     
  162.         if (*m0 || *m1 || mat[2][2] != 0x10000)
  163.         {    Fixed tmp = FracMul(*m0, xTemp) + FracMul(*m1, yTemp);
  164.             tmp += mat[2][2];
  165.             if (tmp && tmp != 0x10000)
  166.             {    *x = FixDiv(*x, tmp);
  167.                 *y = FixDiv(*y, tmp);
  168.             }
  169.         }
  170.         x++;
  171.         y++;
  172.     }
  173. }
  174.  
  175. #define APPENDHANDLE(a,b)    AppendHandle((Handle)a, (Handle)b)
  176.  
  177. void AppendHandle(Handle dst, Handle extra)
  178. {
  179.     long dstSize = GetHandleSize(dst);
  180.     long extraSize = GetHandleSize(extra);
  181.     
  182.     SetHandleSize(dst, dstSize + extraSize);
  183.     if (MemError())
  184.         Debugger();
  185.     else
  186.         BlockMove(*extra, *dst + dstSize, extraSize);
  187. }
  188.  
  189. /*    a += b
  190. */
  191. void AppendGlyphOutline(GlyphOutline* a, GlyphOutline* b)
  192. {
  193.     APPENDHANDLE(a->endPoints, b->endPoints);
  194.     {    short* p = *a->endPoints + a->contourCount;
  195.         short* endp = p + b->contourCount;
  196.         short newFirstPoint = a->contourCount ? p[-1] + 1 : 0;
  197.         for (; p < endp; p++)
  198.             *p = *p + newFirstPoint;
  199.     }
  200.     a->contourCount += b->contourCount;
  201.     a->pointCount += b->pointCount;
  202.     APPENDHANDLE(a->onCurve, b->onCurve);
  203.     APPENDHANDLE(a->x, b->x);
  204.     APPENDHANDLE(a->y, b->y);
  205. }
  206.  
  207. void FrameText( unsigned char* text, FixPoint* scale, int mark )
  208. {
  209.     FixPoint pen;
  210.     paths* myPath = Text2Paths( text, scale, &pen );
  211.  
  212.     if (myPath)
  213.     {    FramePaths(myPath, true);
  214.         if (mark)
  215.             MarkPaths( myPath );    
  216.         DisposePaths(myPath);
  217.         fmoveto( pen.x, pen.y );
  218.     }
  219. }
  220.  
  221. paths* Text2Paths( unsigned char* text, FixPoint* scale, FixPoint* pen )
  222. {
  223.     unsigned state;
  224.     Handle sfnt = GetSfntHandle( qd.thePort->txFont, qd.thePort->txFace );
  225.     paths* compositPath = 0;
  226.  
  227.     if (!sfnt)
  228.         return 0;
  229.  
  230.     state = HGetState( sfnt );
  231.     HNoPurge( sfnt );
  232.  
  233.     {    GlyphOutline out;
  234.         Fixed originX = ff(qd.thePort->pnLoc.h);
  235.         Fixed originY = ff(qd.thePort->pnLoc.v);
  236.         Fixed xScale = scale->x * qd.thePort->txSize;
  237.         Fixed yScale = scale->y * qd.thePort->txSize;
  238.         int i;
  239.  
  240.         InitGlyphOutline( &out );
  241.         for (i = 1; i <= text[0]; i++)
  242.         {    long glyphIndex = GetCharGlyphIndex( sfnt, text[i] );
  243.             GetGlyphOutline( sfnt, glyphIndex, &out, 0 );
  244.             ScaleGlyphOutline( &out, xScale, yScale );
  245.             MoveToGlyphOutline( &out, originX, originY );
  246.  
  247.             {    paths* p = OutlineToPaths( &out );
  248.                 compositPath = AppendPaths( compositPath, p );
  249.                 DisposePaths(p);
  250.             }
  251.             originX += out.advance.x;
  252.             originY += out.advance.y;
  253.         }
  254.         KillGlyphOutline( &out );
  255.         
  256.         if (pen)
  257.         {    pen->x = originX;
  258.             pen->y = originY;
  259.         }
  260.     }
  261.     HSetState( sfnt, state );
  262.     
  263.     return compositPath;
  264. }
  265.  
  266. static long* PackControlBits(long* p, Byte* onCurve, long count);
  267. static long* PackControlBits(long* p, Byte* onCurve, long count)
  268. {
  269.     unsigned long mask = 0x80000000;
  270.     
  271.     *p = 0;
  272.     while (count--)
  273.     {    if (!mask)
  274.         {    mask = 0x80000000;
  275.             *++p = 0;
  276.         }
  277.         if (!*onCurve++)
  278.             *p |= mask;
  279.         mask >>= 1;
  280.     }
  281.     return p + 1;
  282. }
  283.  
  284. paths* OutlineToPaths(GlyphOutline* out)
  285. {
  286.     long size, *p, *origP;
  287.  
  288.     size = sizeof(long);        /* paths.contours */
  289.  
  290.     {    long i, sp = 0;
  291.         for (i = 0; i < out->contourCount; i++)
  292.         {    long pts = (*out->endPoints)[i] - sp + 1;
  293.             size += sizeof(long);            /* path.vectors */
  294.             size += (pts + 31 >> 5) << 2;    /* path.controlBits */
  295.             size += pts << 3;            /* path.vector[] */
  296.             sp = (*out->endPoints)[i] + 1;
  297.         }
  298.     }
  299.  
  300.     origP = p = (long*)NewPtr( size );
  301.     if (!p || MemError())    Debugger();
  302.  
  303.     *p++ = out->contourCount;
  304.     {    long i, sp = 0;
  305.         Fixed* x = *out->x;
  306.         Fixed* y = *out->y;
  307.         short* ep = *out->endPoints;
  308.         Byte* onCurve = *out->onCurve;
  309.         for (i = 0; i < out->contourCount; i++)
  310.         {    long pts = *ep - sp + 1;
  311.             *p++ = pts;
  312.             p = PackControlBits(p, onCurve, pts);
  313.             onCurve += pts;
  314.             while (pts--)
  315.             {    *p++ = *x++;
  316.                 *p++ = *y++;
  317.             }
  318.             sp = *ep++ + 1;
  319.         }
  320.     }
  321.     return (paths*)origP;
  322. }
  323.  
  324.